package com.loongtech.bi.action.newsystem;

import com.loongtech.bi.action.authManagement.ResultData;
import com.loongtech.bi.entity.POJO.Page;
import com.loongtech.bi.entity.system.EntityBiChannel;
import com.loongtech.bi.entity.system.EntityGameParam;
import com.loongtech.bi.manager.system.GameParamConfigManager;
import com.loongtech.bi.manager.system.GameParamTypeConfigManager;
import com.loongtech.bi.manager.system.SyncInfoLogManager;
import com.loongtech.bi.manager.system.SysLogManager;
import com.loongtech.bi.support.ExcelUtils;
import com.loongtech.bi.support.Session;
import com.loongtech.core.util.RetCode;
import com.loongtech.core.util.Time;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.datanucleus.util.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Author: yuri
 * Description: 游戏参数配置
 * Date: 11:57 2017/5/24
 */
@RestController
@Scope("prototype")
@RequestMapping("/gameparam")
public class GameParamsConfigAction {
    @Resource
    private GameParamConfigManager gameParamConfigManager;
    @Resource
    private GameParamTypeConfigManager gameParamTypeConfigManager;
    @Resource
    private Session session;
    @Resource
    private SysLogManager sysLogManager;
    @Resource(name = "systemConfig")
    private SystemConfig systemConfig;
    @Resource
    private SyncInfoLogManager syncInfoLogManager;

    private static String DeleteSQLPre = "delete from bi_game_param where paramtype = ";
    private static String InsertSQLPre = "insert into bi_game_param(gameId,paramtype,paramid,paramname,seq,updateAt) values";

    @RequestMapping(value = "upload", method = {RequestMethod.POST})
    public ResultData<String> upload(@RequestParam(value = "file", required = false) CommonsMultipartFile file, @RequestParam(defaultValue = "0") Integer uploadparamtype) throws IOException {
        System.out.println("upload file.......: ");
        if (file == null || file.getSize() <= 0 || file.getOriginalFilename() == null) {
            return new ResultData<>(RetCode.eEmptyUploadFile.getErrorcode(), RetCode.eEmptyUploadFile.getErrorMsg());
        }
//        if (uploadparamtype == 0) {
//            return new ResultData<>(RetCode.eEmptyParamType.getErrorcode(), RetCode.eEmptyParamType.getErrorMsg());
//        }
        String fileName = file.getOriginalFilename();
        String id = UUID.randomUUID().toString();
        // 文件的相对路径
        String subPath = "GameParamConfig_" + id + "_" + fileName;
        // 文件的绝对路径
        String filePath = systemConfig.getFileParentPath() + subPath;
        File tmpdir = new File(systemConfig.getFileParentPath());
        if (!tmpdir.exists()) {
            tmpdir.mkdir();
        }
        File newfile = new File(filePath);
        try {
            FileUtils.copyInputStreamToFile(file.getInputStream(), newfile);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResultData<>(RetCode.eIOUploadFile.getErrorcode(), RetCode.eIOUploadFile.getErrorMsg());
        }
        return parseExcel(newfile);
    }

    public ResultData<String> parseExcel(File file) {
        try {
            List<EntityGameParam> tmp = parseUploadedExcel(file);
            if (tmp != null && tmp.size() > 0) {
                String gameIds = tmp.get(0).getGameId();
                int paramType = tmp.get(0).getParamtype();
                // 同步sql
                StringBuffer insertSQLEnd = new StringBuffer();
                // 删老数据
                List<EntityGameParam> te = gameParamConfigManager.findByQuery("from EntityGameParam where 1=1 and paramtype = ? ", paramType);
                if (te != null && te.size() > 0) {
                    for (EntityGameParam param : te) {
                        String gids = param.getGameId();

                        if (gids.equals(gameIds)) {
                            gameParamConfigManager.removeById(param.getId());
                        } else {
                            for (String gid : gameIds.split(",")) {
                                if (gids.equals(gid + ",")) {
                                    gameParamConfigManager.removeById(param.getId());
                                } else {
                                    if (gids.contains(gid + ",")) {
                                        gids = gids.replace(gid + ",", "");
                                        param.setGameId(gids);
                                        gameParamConfigManager.merge(param);
                                    }
                                }
                            }
                        }
                    }
                }
                // 插新数据
                for (EntityGameParam param : tmp) {
                    gameParamConfigManager.persist(param);
                    insertSQLEnd.append("(").append("'").append(gameIds).append("',").append(paramType).append(",'").append(param.getParamid()).append("','").append(param.getParamname()).append("',").append(param.getSeq()).append(",").append(Time.currentTime()).append("),");
                }

                String dsql = DeleteSQLPre + paramType;
                String isql = InsertSQLPre + insertSQLEnd.substring(0, insertSQLEnd.length() - 1);

                // 插入同步表
                StringBuilder excuteSql = new StringBuilder();
                excuteSql.append(dsql).append(";").append(isql);
                for (String gid : gameIds.split(",")) {
                    syncInfoLogManager.add(gid, excuteSql.toString());
                }
                gameParamConfigManager.init();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultData<>(RetCode.eParseExcel.getErrorcode(), RetCode.eParseExcel.getErrorMsg());
        } finally {
            if (file != null && file.exists()) {
                file.delete();
            }
        }
        return ResultData.success();
    }

    private List<EntityGameParam> parseUploadedExcel(File file) throws Exception {
        List<EntityGameParam> result = new ArrayList<>();
        InputStream input = new FileInputStream(file);
        Workbook wb = WorkbookFactory.create(input);
        Sheet tempSheet = wb.getSheetAt(0);
        if (tempSheet == null) {
            IOUtils.closeQuietly(input);
            System.out.println("Error---------------------------excel内容为空,数据错误！");
            throw new Exception("excel内容为空,数据错误");
        }
        String firstType = "";
        int rowNum = tempSheet.getLastRowNum();// 获得总行数
        for (int i = 0; i <= rowNum; i++) {
            Row row = tempSheet.getRow(i);
            if (row == null) {
                continue;
            }
            String gameId = ExcelUtils.getCellValue(row.getCell(0));
            String type = ExcelUtils.getCellValue(row.getCell(1));
            String key = ExcelUtils.getCellValue(row.getCell(2));
            String value = ExcelUtils.getCellValue(row.getCell(3));
            String sort = ExcelUtils.getCellValue(row.getCell(4));
            if ("".equals(type) || "".equals(key) || "".equals(key) || "".equals(gameId)) {
                continue;
            }
            if (i == 0) {
                firstType = type;
            } else {
                if (!firstType.equals(type)) {
                    IOUtils.closeQuietly(input);
                    System.out.println("Error---------------------------类型列数据不一致！");
                    throw new Exception("类型列数据不一致！");
                }
            }
            EntityGameParam e = new EntityGameParam();
            e.setGameId(gameId);
            e.setParamtype(Integer.parseInt(type));
            e.setParamid(key);
            e.setParamname(value);
            e.setSeq(StringUtils.isEmpty(sort) ? 0 : Integer.parseInt(sort));
            result.add(e);
        }
        IOUtils.closeQuietly(input);
        return result;
    }

    /**
     * 查询
     */
    @RequestMapping(value = "list.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultData<?> searchByCriteria(@RequestParam Integer curPage, @RequestParam Integer pageSize, EntityGameParam entity) {
        Page<List<EntityGameParam>> list;
        try {
            list = gameParamConfigManager.queryByCriteria(curPage, pageSize, entity);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultData.otherException();
        }
        return new ResultData<>(RetCode.eSuccess.getErrorcode(), list);
    }

    /**
     * 参数类型下拉列表
     */
    @RequestMapping(value = "paramtypes.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultData<?> searchByCriteria() {
        List<EntityBiChannel> list;
        try {
            list = gameParamTypeConfigManager.findByQuery("select id, name from EntityGameParamType");
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultData.otherException();
        }
        return new ResultData<>(RetCode.eSuccess.getErrorcode(), list);
    }


    @RequestMapping(value = "add.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultData<String> add(EntityGameParam entity) {
        if (entity.getGameId() == null) {
            return new ResultData<>(RetCode.eEmptyGameId.getErrorcode(), RetCode.eEmptyGameId.getErrorMsg());
        }
        if (entity.getParamid() == null) {
            return new ResultData<>(RetCode.eEmptyId.getErrorcode(), RetCode.eEmptyId.getErrorMsg());
        }
        if (entity.getParamtype() == 0) {
            return new ResultData<>(RetCode.eEmptyParamType.getErrorcode(), RetCode.eEmptyParamType.getErrorMsg());
        }
        if (entity.getParamname() == null || "".equals(entity.getParamname())) {
            return new ResultData<>(RetCode.eEmptyParamValue.getErrorcode(), RetCode.eEmptyParamValue.getErrorMsg());
        }
        try {
            if (gameParamConfigManager.canAddNew(entity)) {
                gameParamConfigManager.persist(entity);

                StringBuilder insertSQLEnd = new StringBuilder();
                insertSQLEnd.append("(").append("'").append(entity.getGameId()).append("',").append(entity.getParamtype()).append(",'").append(entity.getParamid()).append("','").append(entity.getParamname()).append("',").append(entity.getSeq()).append(",").append(Time.currentTime()).append(")");
                String isql = InsertSQLPre + insertSQLEnd;
                // 插入同步表
                for (String gid : entity.getGameId().split(",")) {
                    syncInfoLogManager.add(gid, isql);
                }

                gameParamConfigManager.init();
                return ResultData.success();
            } else {
                return new ResultData<>(RetCode.eIDorNameExist.getErrorcode(), RetCode.eIDorNameExist.getErrorMsg());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultData.otherException();
        }
    }

    @RequestMapping(value = "modify.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultData<String> modify(EntityGameParam entity) {
        if (entity.getGameId() == null) {
            return new ResultData<>(RetCode.eEmptyGameId.getErrorcode(), RetCode.eEmptyGameId.getErrorMsg());
        }
        if (entity.getParamid() == null) {
            return new ResultData<>(RetCode.eEmptyId.getErrorcode(), RetCode.eEmptyId.getErrorMsg());
        }
        if (entity.getParamtype() == 0) {
            return new ResultData<>(RetCode.eEmptyParamType.getErrorcode(), RetCode.eEmptyParamType.getErrorMsg());
        }
        if (entity.getParamname() == null || "".equals(entity.getParamname())) {
            return new ResultData<>(RetCode.eEmptyParamValue.getErrorcode(), RetCode.eEmptyParamValue.getErrorMsg());
        }
        return gameParamConfigManager.modifyByEntity(entity);
    }

    @RequestMapping(value = "delete.do", method = {RequestMethod.GET, RequestMethod.POST})
    public ResultData<String> delete(Integer id) {
        return gameParamConfigManager.removeByEntity(id);
    }
}
